import socket
import ssl

# Core dos downloads
def download(link: str, filename: str="downloaded"):

    redirect = False

    while True:
        if "https://" in link:
            link = link.replace('https://', '')
        elif "http://" in link:
            link = link.replace('http://', '')

        if "www." in link:
            link = link.replace('www.', '')

        if '/' in link:
            host = link[:link.index('/')]
            path = link[link.index('/'):]
        else:
            raise ValueError("Obtivemos uma dificuldade em encontrar o caminho. Revise o link solicitado.")
        
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if redirect:
            context = ssl.create_default_context()
            s = context.wrap_socket(s, server_hostname=host)
            s.connect((host, 443))
        else:
            try:
                s.connect((host, 80))
            except:
                raise socket.gaierror("Obtivemos uma dificuldade em encontrar o nome do destinatario. Revise o link solicitado.")

        r = f"GET {path} HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n"
        s.sendall(r.encode())

        response = b""
        while True:
            data = s.recv(4096)
            if not data:
                break
            response += data

        # Resposta
        split_response = response.find(b'\r\n\r\n') + 4
        headers = response[:split_response].decode('utf-8')
        body = response[split_response:]

        print(filename)
        print(headers)

        # detecta o tipo do arquivo
        try:
            file_extension = filename[1-filename.index('.'):]
        except ValueError:
            lambda_content_type = lambda headers: [line for line in headers.split('\n') if 'Content-Type:' in line]
            content_type = lambda_content_type(headers)[0].strip()
            if 'image/jpeg' in content_type:
                filename = f'{filename}.jpg'
            elif 'audio/mpeg' in content_type:
                filename = f'{filename}.mp3'
            elif 'video/mp4' in content_type:
                filename = f'{filename}.mp4'
            else:
                filename = f'{filename}'
        
        # Verifica se o retorno foi OK
        if "HTTP/1.1 200" in headers:
            break
        elif "HTTP/1.1 301" in headers or "HTTP/1.1 302" in headers:
            for line in headers.split("\r\n"):
                if line.startswith("Location:"):
                    link = line.split("Location: ")[1]
                    redirect = True
        else:
            print('Necessario checar')
            break

    # Salva o corpo da resposta como um arquivo
    with open(filename, 'wb') as file:
        file.write(body)

'''
# É necessário o link direto do video ou musica
files_for_downlaod = ['https://videos.pond5.com/sunset-pink-and-purple-cumulus-footage-083756947_main_xxl.mp4',
                      'https://ncs.io/track/download/2b08f7d9-4f5f-47bd-a608-07dec1f7eaa9?_gl=1*pj92ed*_up*MQ..*_ga*NDU0NDM0MTI2LjE3NDAxNjQ1MjM.*_ga_PFS54FR7NV*MTc0MDE2NDUyMy4xLjAuMTc0MDE2NDU2OS4wLjAuMA..',
                      'https://images.unsplash.com/photo-1533450718592-29d45635f0a9?fm=jpg&q=60&w=3000&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8anBnfGVufDB8fDB8fHww',]

i = 0
for link in files_for_downlaod:
    name = f'download_{i}'
    download(link, name)
    i +=1
'''